#include "vt100.h"
#include "my_console.h"
#include "key_read.h"
#include "menu.h"
#include "utf8.h"
#include "extend_color.h"
#include "cmd_input.h"
#include "pixel_data.h"

#include "wnd.h"

#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>   // 包含 kbhit() 和 getch() 函数的头文件
#include <windows.h> // 包含 Sleep() 函数的头文件

#define APP_OK_KEY 0
#define APP_EXIT_KEY 1

#define MOVE_X_STEP 2
#define MOVE_Y_STEP 1

#define blockWidth 17
#define blockHeight 16

size_t g_width = 0;
size_t g_height = 0;

Array2D* array = NULL;

// uint16_t G_WIDTH = blockWidth * 2;  // 画布宽度
// uint16_t G_HEIGHT = blockHeight; // 画布高度
// uint8_t screenColor[blockHeight][blockWidth] = {0}; // 行*列

uint16_t cursorX = 0;
uint16_t cursorY = 0;

vt_fore_color G_FG_COLOR = VT_F_WHITE;
vt_back_color G_BG_COLOR = VT_B_BLUE;

const STColor *G_EXTEND_COLOR = &COLOR_GREEN;

uint16_t G_MARGIN_LEFT = 4; // 内容左边距
uint16_t G_MARGIN_TOP = 4; // 内容上边距

typedef struct
{
    STPoint p;
    const STColor* color[10];
    uint8_t size;
}STColorCard;

STColorCard g_color_card;

void RenderColor()
{
    reset_colors();
    print_array_as_hex(array, G_MARGIN_LEFT + g_width * 2, G_MARGIN_TOP);
    // int bytesPerRow = (blockWidth + 7) / 8; // 计算每行需要的字节数
    // for (int row = 0; row < blockHeight; row++) {
    //     MoveCursorTo(G_MARGIN_LEFT + g_width * 2 + 2, G_MARGIN_TOP + row);
    //     for (int byteIdx = 0; byteIdx < bytesPerRow; byteIdx++) {
    //         uint8_t byte = 0;
    //         // 处理当前字节对应的8个元素（可能包含补零）
    //         for (int bit = 0; bit < 8; bit++) {
    //             int col = byteIdx * 8 + bit;
    //             if (col < blockWidth && screenColor[row][col] != 0) {
    //                 byte |= (1 << (7 - bit)); // 设置对应位为1
    //             }
    //         }
    //         printf("%02X", byte);
    //     }
    // }
}

int main1()
{
    system("chcp 65001");
    STRect rect = {{0, 0}, 20, 2}; // 矩形区域：左上角 (10, 10)，宽 20，高 5
    // uint8_t str[] = "123456789012345中文1234";     // 测试字符串
    char str[] = "123456";     // 测试字符串

    // CenterStrUtf8(str, &rect, strlen(str));
    DrawCenterStrInRectUTF8(str, strlen((char*)str), &rect);
    return 0;
}

void ColorCardInit()
{
    g_color_card.p.x = 2;
    g_color_card.p.y = 3;
    g_color_card.color[0] = &COLOR_RED;
    g_color_card.color[1] = &COLOR_GREEN;
    g_color_card.color[2] = &COLOR_BLUE;
    g_color_card.color[3] = &COLOR_WHITE;
    g_color_card.color[4] = &COLOR_BLACK;
    g_color_card.color[5] = &COLOR_YELLOW;
    g_color_card.color[6] = &COLOR_CYAN;
    g_color_card.color[7] = &COLOR_MAGENTA;
    g_color_card.size = 8;
}

void RenderColorBlock()
{
    ColorCardInit();
    MoveCursorTo(g_color_card.p.x, g_color_card.p.y);
    for (uint8_t i = 0; i < g_color_card.size; i++) {
        print_colored_square(g_color_card.color[i]);
    }
}

void RenderTitle()
{
    SetBgColor(VT_B_PURPLE);
    FillBox(0, 0, g_width * 2 +  2 * G_MARGIN_LEFT, G_MARGIN_TOP);
    // DrawStrAtPos(G_MARGIN_LEFT, 0, ); // TODO:: 增加越界限制
    char* title = "你好 console.";

    STRect rectTitle = {{0, 0},  2 * G_MARGIN_LEFT + g_width * 2, 1};
    DrawCenterStrInRectUTF8(title, strlen(title), &rectTitle);
    DrawHorizontalLine(0, 1, g_width * 2 +  2 * G_MARGIN_LEFT);

    char* menus[] = {"File", "编辑C", "保存","Help"};

    STMenu menu;
    uint8_t padding = 2;
    uint8_t startLeft = 1;

    MenuInit(&menu, 2); // 初始化菜单，初始容量为2
    uint32_t x = startLeft;
    for (size_t i = 0; i < sizeof(menus) / sizeof(menus[0]); i++) {
        STMenuItem item;
        item.rect.width = UTF8GetStrShowWidth((uint8_t*)menus[i]);
        item.rect.height = 1;
        if (i == 0) {
            item.rect.p.x = x;
        } else {
            x += UTF8GetStrShowWidth((uint8_t*)menus[i - 1]) + padding;
            item.rect.p.x = x;
        }
        item.rect.p.y = 2;

        item.str = strdup(menus[i]);
        MenuAddItem(&menu, item);
    }
    MenuRender(&menu);
    MenuDestroy(&menu);
    
    SetBgColor(G_BG_COLOR);
}

void RenderLineNum()
{
    reset_colors();
    for (int i = 0; i < blockHeight; i++) {
        char numStr[6] = {0};
        MoveCursorTo(0, G_MARGIN_TOP + i);
        int ret = snprintf(numStr, 5, "%02d.", i + 1);
        if (ret < 0) {
            printf("Error: snprintf failed with return value %d\n", ret);
            return;
        } else if (ret >= (int)sizeof(numStr)) {
            printf("Buffer too small! Required size: %d\n", ret + 1);
            return;
        }
        print_colored_string(&COLOR_YELLOW, numStr);
    }
}

void MyMoveRight()
{
    if (cursorX + MOVE_X_STEP <= (uint16_t)(g_width * 2 + G_MARGIN_LEFT)) {
        MoveRight(MOVE_X_STEP);
        cursorX += MOVE_X_STEP;
    }
}

void MyMoveLeft()
{
    if (cursorX > 0) {
        MoveLeft(MOVE_X_STEP);
        cursorX -= MOVE_X_STEP;
    }
}

void MyMoveDown()
{
    if (cursorY + MOVE_Y_STEP < (uint16_t)(g_height + G_MARGIN_TOP)) {
        MoveDown(MOVE_Y_STEP);
        cursorY += MOVE_Y_STEP;
    }
}

void MyMoveUp()
{
    if (cursorY > 0) {
        MoveUp(MOVE_Y_STEP);
        cursorY -= MOVE_Y_STEP;
    }
}

void BackSpcace()
{
    if (cursorX < MOVE_X_STEP + G_MARGIN_LEFT)
        return;
    SetBgColor(G_BG_COLOR);
    // screenColor[cursorY - G_MARGIN_TOP][(cursorX - G_MARGIN_LEFT) / 2 - 1] = 0;
    Coordinate coord1 = {(cursorX - G_MARGIN_LEFT) / 2 - 1, cursorY - G_MARGIN_TOP};
    set_value(array, coord1, 0x00000000);

    FillBox(cursorX - MOVE_X_STEP, cursorY, MOVE_X_STEP, MOVE_Y_STEP);
    cursorX -= MOVE_X_STEP;
}

void EnterClick()
{
    if (cursorY == g_color_card.p.y && cursorX >= 2) {
        if (((cursorX - 2) / 2) < g_color_card.size) {
            G_EXTEND_COLOR = g_color_card.color[(cursorX - 2) / 2];
        }
    }
}

void ColorFill()
{
    if (cursorX + MOVE_X_STEP > (uint16_t)(g_width * 2 + G_MARGIN_LEFT) || cursorX < G_MARGIN_LEFT || cursorY < G_MARGIN_TOP)
        return;
    set_bg_color(G_EXTEND_COLOR);

    Coordinate coord1 = {(cursorX - G_MARGIN_LEFT) / 2, cursorY - G_MARGIN_TOP};
    uint32_t uColor = stcolor_to_u32(G_EXTEND_COLOR);
    set_value(array, coord1, uColor);
    MoveCursorTo(0, G_MARGIN_TOP + g_height + 1);
    printf("%02d--%02d--%x", cursorX, cursorY, uColor); // agrb

    FillBox(cursorX, cursorY, MOVE_X_STEP, MOVE_Y_STEP);
    SetBgColor(G_BG_COLOR);
    cursorX += MOVE_X_STEP;
}

int deal_key()
{
    KeyInput key = read_key(); // 调用封装的函数读取键值
    if (key.value != 0)
    { // 如果有按键输入
        if (key.is_special_key)
        { // 特殊键处理
            switch (key.value)
            {
            case KEY_UP:
                MyMoveUp();
                // printf("方向键: 上 (0x%02X)\n", key.value);
                break;
            case KEY_DOWN:
                MyMoveDown();
                // printf("方向键: 下 (0x%02X)\n", key.value);
                break;
            case KEY_LEFT:
                MyMoveLeft();
                // printf("方向键: 左 (0x%02X)\n", key.value);
                break;
            case KEY_RIGHT:
                MyMoveRight();
                // printf("方向键: 右 (0x%02X)\n", key.value);
                break;
            case KEY_DELETE:
                // BackSpcace();
                printf("特殊键: Delete (0x%02X)\n", key.value);
                break;
            default:
                if (key.value >= KEY_F1 && key.value <= KEY_F12)
                {
                    printf("功能键: F%d (0x%02X)\n", key.value - KEY_F1 + 1, key.value);
                }
                else
                {
                    printf("未知特殊键: 0x%02X\n", key.value);
                }
                break;
            }
        }
        else
        { // 普通字符处理
            switch (key.value)
            {
            case KEY_BACKSPACE:
                BackSpcace();
                // printf("特殊键: Backspace (0x%02X)\n", key.value);
                break;
            case KEY_ENTER:
                // printf("特殊键: Enter (0x%02X)\n", key.value);
                EnterClick();
                break;
            case KEY_ESC:
                printf("ESC 键按下 (0x%02X)，程序退出。\n", key.value);
                return APP_EXIT_KEY; // 退出程序
            default:
                ColorFill();
                // printf("普通键: %c (ASCII: 0x%02X)\n", key.value, key.value);
                break;
            }
        }
        RenderColor();
        MoveCursorTo(cursorX, cursorY);
    }
    return APP_OK_KEY;
}

int main(int argc, char* argv[])
{
    int ret = get_cmd_input(argc, argv, &g_width, &g_height);
    if (ret != EXIT_SUCCESS) {
        return ret;
    }

    array = allocate_2d_array(g_width, g_height);
    if (!array) {
        fprintf(stderr, "Failed to allocate 2D array\n");
        return EXIT_FAILURE;
    }

    system("chcp 65001");
    StoreScreen();
    DisEnableCursor();

    SetFgColor(G_FG_COLOR);
    SetBgColor(G_BG_COLOR);
    FillBox(G_MARGIN_LEFT, G_MARGIN_TOP, g_width * 2, g_height);
    RenderBox(G_MARGIN_LEFT, G_MARGIN_TOP, g_width * 2, g_height);
    RenderTitle();
    RenderLineNum();
    RenderColorBlock();

    EnableCursor();
    cursorX = G_MARGIN_LEFT;
    cursorY = G_MARGIN_TOP;
    MoveCursorTo(G_MARGIN_LEFT, G_MARGIN_TOP);
    while (1)
    {
        if (deal_key() == APP_EXIT_KEY)
        {
            break;
        }

        Sleep(10); // 1000 毫秒 = 1 秒
    }

    const char* image_filename = "output1.rgb";
    save_as_image(array, image_filename);
    free_2d_array(array);

    MoveCursorTo(g_width * 2, g_height);
    system("pause");
    RestoreScreen();
    EnableCursor();

    return 0;
}
